﻿
using System.Collections.Generic;

namespace Anno.DynamicApi
{
    /// <summary>
    /// 控制器信息
    /// </summary>
    public class ControllerInfo
    {
        /// <summary>
        /// 命名空间
        /// </summary>
        public string Namespace { get; set; }

        /// <summary>
        /// 控制器名称
        /// </summary>
        public string ControllerName { get; set; }

        /// <summary>
        /// 默认连接配置中的connectionStrings节点名称，connectionStrings[DBName]
        /// </summary>
        public string DefaultDBName { get; set; }
        /// <summary>
        /// 返回结果是否为驼峰命名
        /// </summary>
        public bool IsCamelCaseNames { get; set; } = false;
        ///// <summary>
        ///// 是否启用授权服务Token
        ///// </summary>
        //public bool UseToken { get; set; }

        ///// <summary>
        ///// 是否启用数据签名
        ///// </summary>
        //public bool UseDataSign { get; set; }

        ///// <summary>
        ///// 是否启用加密/解密
        ///// </summary>
        //public bool UseEncrypt { get; set; }
        ///// <summary>
        ///// 解密字段名（为空表示解密整个消息体）
        ///// </summary>
        //public string EncryptFiled { get; set; } = "";
        ///// <summary>
        ///// 密钥
        ///// </summary>
        //public string SecretKey { get; set; } = "SHRJHLWYY@2020";
        ///// <summary>
        ///// 密钥向量
        ///// </summary>
        //public string SecretIV { get; set; } = "";
        ///// <summary>
        ///// 对称加密类型（AES128 ,AES192 ,AES256 ,DES ,TripleDES128 ,TripleDES192 ,SM4JAVA ,SM4JS ,SM4  ）
        ///// </summary>
        //public string EncryptType { get; set; } = "SM4";

        /// <summary>
        /// 控制器的路由前缀
        /// </summary>
        public string RoutePrefix { get; set; }
        /// Action列表
        /// </summary>
        public List<ApiInfo> ApiInfoList { get; set; } = new List<ApiInfo>();

        ///// <summary>
        ///// 0=动态编译类型，1=动态库（DLL）
        ///// </summary>
        //public int ControllerType { get; set; }

        ///// <summary>
        ///// 动态库（DLL）路径
        ///// </summary>
        //public string ServiceDllPath { get; set; }
        ///// <summary>
        /////  动态库（DLL）服务类全名 fullname（Namespace.Service）
        ///// </summary>
        //public string assemblyTypeName { get; set; }
        ///// <summary>
        /////  动态库（DLL）服务协议全名 fullname （Namespace.IService）
        ///// </summary>
        //public string contractTypName { get; set; }

        /// <summary>
        /// 标题/中文名
        /// </summary>
        public string Title { get; set; }
        /// <summary>
        /// 备注
        /// </summary>
        public string Remark { get; set; }

        public System.Xml.XmlNode XMLNode { get; set; }
        public string GroupId { get; set; }
        /// <summary>
        /// 返回JSON对象
        /// </summary>
        public virtual object JObject
        {
            get
            {
                var dyret = DicAttrs;
                var apiInfoList = new List<object>();
                dyret["ApiInfoList"] = apiInfoList;
                return dyret;
                //var apiInfoList = new List<object>();

                //return new
                //{
                //    Name = ControllerName,
                //    RoutePrefix,
                //    Namespace,
                //    DefaultDBName,
                //    Remark,
                //    Title,
                //    IsCamelCaseNames,
                //    ApiInfoList = apiInfoList,
                //};
            }
        }
        public virtual IDictionary<string, object> DicAttrs
        {
            get
            {
                var ret = new System.Dynamic.ExpandoObject();
                IDictionary<string, object> dyret = ret;

                dyret["Name"] = ControllerName;
                dyret["RoutePrefix"] = RoutePrefix;
                dyret["Namespace"] = Namespace;
                dyret["Title"] = Title;
                dyret["Remark"] = Remark;
                dyret["DefaultDBName"] = DefaultDBName;
                dyret["IsCamelCaseNames"] = IsCamelCaseNames;
                dyret["GroupId"] = GroupId;

                return ret;
            }
        }
        /// <summary>
        /// 返回JSON对象,包括明细
        /// </summary>
        public virtual object JObjects
        {
            get
            {
                var dyret = DicAttrs;
                var apiInfoList = new List<object>();
                ApiInfoList?.ForEach(ext => apiInfoList.Add(ext.JObject));
                dyret["ApiInfoList"] = apiInfoList;
                return dyret;

                //var apiInfoList = new List<object>();
                //ApiInfoList?.ForEach(ext => apiInfoList.Add(ext.JObject));

                //return new
                //{
                //    Name = ControllerName,
                //    RoutePrefix,
                //    Namespace,
                //    DefaultDBName,
                //    Remark,
                //    Title,
                //    IsCamelCaseNames,
                //    ApiInfoList = apiInfoList,
                //};
            }
        }
        /// <summary>
        /// 控制器
        /// </summary>
        public ControllerInfo()
        {
        }
        /// <summary>
        /// 控制器
        /// </summary>
        /// <param name="xmlNode"></param>
        public ControllerInfo(System.Xml.XmlNode xmlNode)
        {
            Init(xmlNode);
        }
        public void Init(System.Xml.XmlNode controllerNode)
        {
            try
            {
                XMLNode = controllerNode;
                if (controllerNode == null || controllerNode.NodeType == System.Xml.XmlNodeType.Comment)
                {
                    return;
                }
                ControllerName = PubFun.GetXmlNodeAttributeValue(controllerNode, "Name");
                RoutePrefix = PubFun.GetXmlNodeAttributeValue(controllerNode, "RoutePrefix", "api/" + ControllerName);// /HCenter;

                Namespace = PubFun.GetXmlNodeAttributeValue(controllerNode, "Namespace", "HCenter.DynamicApi").TrimEnd('.');
                DefaultDBName = PubFun.GetXmlNodeAttributeValue(controllerNode, "DefaultDBName", "BaseDb");
                GroupId = PubFun.GetXmlNodeAttributeValue(controllerNode, "GroupId", "0");

                Title = PubFun.GetXmlNodeAttributeValue(controllerNode, "Title", ControllerName);
                Remark = PubFun.GetXmlNodeAttributeValue(controllerNode, "Remark", Title);

                IsCamelCaseNames = PubFun.GetXmlNodeAttributeValue(controllerNode, "IsCamelCaseNames", "false").ChangeType<bool>();

                //UseToken = PubFun.GetXmlNodeAttributeValue(controllerNode, "UseToken", "false").ChangeType<bool>();
                //UseDataSign = PubFun.GetXmlNodeAttributeValue(controllerNode, "UseDataSign", "false").ChangeType<bool>();
                //UseEncrypt = PubFun.GetXmlNodeAttributeValue(controllerNode, "UseEncrypt", "false").ChangeType<bool>();
                //EncryptFiled = PubFun.GetXmlNodeAttributeValue(controllerNode, "EncryptFiled", "");
                //SecretKey = PubFun.GetXmlNodeAttributeValue(controllerNode, "SecretKey", "SHRJHLWYY@2020");
                //SecretIV = PubFun.GetXmlNodeAttributeValue(controllerNode, "SecretIV", "");
                //EncryptType = PubFun.GetXmlNodeAttributeValue(controllerNode, "EncryptType", "SM4");

                //ControllerType = PubFun.GetXmlNodeAttributeValue(controllerNode, "ControllerType", "0").ChangeType<int>();
                //ServiceDllPath = PubFun.GetXmlNodeAttributeValue(controllerNode, "ServiceDllPath");
                //assemblyTypeName = PubFun.GetXmlNodeAttributeValue(controllerNode, "assemblyTypeName");
                //contractTypName = PubFun.GetXmlNodeAttributeValue(controllerNode, "contractTypName");
            }
            catch { }

            //判断controller属性
            if (ControllerName.IsNullOrEmpty())
            {
                showException("<Controller Name属性不能为空");
            }
            //2. 获得所有Api节点
            this.ApiInfoList = new List<ApiInfo>();
            var apiNodeList = controllerNode.ChildNodes;
            if (apiNodeList == null)
            {
                showException("<Controller Name=" + ControllerName + " 下无 <Api/>子节点");
                return;
            }
            foreach (System.Xml.XmlNode apiNode in apiNodeList)
            {
                #region 2.1. Api Info
                if (apiNode.NodeType == System.Xml.XmlNodeType.Comment)// 判断等于注释时
                {
                    continue;
                }
                var apiName = PubFun.GetXmlNodeAttributeValue(apiNode, "Name").Trim('.');
                if (apiName.IsNullOrEmpty())
                {
                    showException("<Controller Name=" + ControllerName + " 的 <Api Name属性不能为空");
                }
                if (ApiInfoList.Exists(f => f.ApiName.Equals(apiName,System.StringComparison.OrdinalIgnoreCase)))
                {
                    showException($"<Controller Name={ControllerName} 的 <Api Name={apiName}/>名称重复");
                }
                var apiInfo = new ApiInfo(apiNode, this);
                this.ApiInfoList.Add(apiInfo);
                #endregion
            }
        }
        protected void showException(string msg)
        {
            throw new System.Exception("LoadApiControllers Error:" + msg);
        }
    }
}
